cmake_minimum_required(VERSION 3.10)
project(helloworld VERSION 1.0.0 DESCRIPTION "单元测试演示" LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11) # C++11标准
set(CMAKE_CXX_STANDARD_REQUIRED ON) # C++11标准是必须的
set(CMAKE_CXX_EXTENSIONS OFF) # 不使用编译器特定扩展

# =============================== 全局配置 ==========================
# 全局变量
set(ROOT ${CMAKE_CURRENT_SOURCE_DIR})
set(MYLIB helloworld_core)
set(MYEXE helloworld_app)

# 自定义宏(调试模式、启用MOCK、日志颜色)
add_definitions(-DDEBUG -DMOCK -DLOG_COLOR)

# 输出路径(默认为空,可被父CMAK定义覆盖)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT}) # 静态库输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${ARCHIVE_OUTPUT}) # 动态库输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${RUNTIME_LIBRARY}) # 程序文件输出目录

# 资源文件
file(GLOB_RECURSE HEADERS "${ROOT}/include/*.h" "${ROOT}/libs/*.h") # 头文件
file(GLOB_RECURSE SOURCES "${ROOT}/src/*.cpp" "${ROOT}/libs/*.c") # 源文件
list(FILTER SOURCES EXCLUDE REGEX "${ROOT}/src/main.cpp") # 排除文件

# =============================== 生成lib ==========================
add_library(${MYLIB} STATIC ${SOURCES} ${HEADERS}) # 生成静态库
target_include_directories(${MYLIB} PUBLIC ${ROOT}/include ${ROOT}/libs) # 头文件路径

# =============================== 程序项目 ==========================
add_executable(${MYEXE} ${SOURCES} ${HEADERS} ${ROOT}/src/main.cpp) # 可执行程序
target_include_directories(${MYEXE} PRIVATE ${ROOT}/include) # 头文件路径(仅main相关)
target_link_libraries(${MYEXE} PRIVATE ${MYLIB}) # 依赖项目库

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/logs) # 创建日志目录
file(COPY ${CMAKE_SOURCE_DIR}/etc DESTINATION ${CMAKE_BINARY_DIR}) # 拷贝配置文件

# =============================== 条件编译 ==========================
if(WIN32)
    target_link_libraries(${MYLIB} PUBLIC ws2_32) # WinSock2.0_32核心库
    target_link_directories(${MYLIB} PUBLIC "C:/libs") # 静态库路径(可多个)
endif()

if(MSVC) # MSVC无Wextra编译参数; 无须链接pthread库
    target_compile_options(${MYLIB} PUBLIC -g -Wall "/W4") # 调试信息+所有警告+警告级别
    set_property(GLOBAL PROPERTY USE_FOLDERS ON) # 启用VS工程文件组
    set_property(DIRECTORY ${ROOT} PROPERTY VS_STARTUP_PROJECT ${MYEXE}) # 默认启动项
    add_definitions(-D_CRT_SECURE_NO_WARNINGS -DWIN32 -D_WIN32) # VS宏定义
    source_group(TREE ${ROOT} FILES ${SOURCES} ${HEADERS}) # VS目录分组
else()
    target_compile_options(${MYLIB} PUBLIC -g -Wall -Wextra) # 调试信息+所有警告+额外警告
    target_link_libraries(${MYLIB} PUBLIC pthread) # 静态库链接
    target_link_directories(${MYLIB} PUBLIC ${HOME}/local/libs) # 静态库路径(可多个)
endif()

# =============================== 测试项目 ==========================
option(BUILD_TEST "Build test projects" ON)

if(BUILD_TEST)
    enable_testing()
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)
endif()

# =============================== 打包项目 ==========================
if(WIN32)
    include(CPack)
    set(CMAKE_GENERATOR "NISI;ZIP") # 打包方式
    set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) # 打包名称
    set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) # 打包版本
    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
    set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")

    set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/dist) # 打包输出目录
    set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME}) # 安装目录
    set(CPACK_NSIS_MODIFY_PATH ON) # 修改安装路径
    set(CPACK_PACKAGE_EXECUTABLES ${MYEXE} ${MYEXE}) # 启动项

    set(CPACK_CREATE_DESKTOP_LINK ${MYEXE}) # 创建桌面快捷方式
    set(CPACK_NSIS_MUI_ICON ${CMAKE_CURRENT_SOURCE_DIR}/etc/icon.ico) # 安装图标
    set(CPACK_NSIS_MUI_UNIICON ${CMAKE_CURRENT_SOURCE_DIR}/etc/icon.ico) # 卸载图标
    set(CPACK_NSIS_MUI_HEADERIMAGE ${CMAKE_CURRENT_SOURCE_DIR}/etc/header.bmp) # 安装标题
    set(CPACK_NSIS_MUI_HEADERIMAGE_RIGHT ${CMAKE_CURRENT_SOURCE_DIR}/etc/header.bmp) # 安装标题
    set(CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP ${CMAKE_CURRENT_SOURCE_DIR}/etc/wizard.bmp) # 安装向导
    set(CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP ${CMAKE_CURRENT_SOURCE_DIR}/etc/wizard.bmp) # 卸载向导
    set(CPACK_NSIS_MUI_UNINSTALLER_ATTRIBUTE "ShowInstDetails show" "ShowUninstDetails show") # 安装/卸载详情
endif()